/* Copyright (C) 
 * 
 * Disclaim
 * This program is the property of AI Speech Ltd. It shall be communicated to
 * authorized personnel only. It is not to be disclosed outside the group without
 * prior written consent. If you are not sure if you’re authorized to read this
 * program, please contact info@aispeech.com before reading.
 * 
 */

#include "wtk_utils_offinfo.h"
#include "wtk_utils.h"
#include "wtk/core/cfg/wtk_main_cfg.h"



wtk_offinfo_t* wtk_offinfo_new(int len) {
    wtk_offinfo_t *offInfo = wtk_malloc(sizeof(wtk_offinfo_t));
    memset(offInfo, 0, sizeof(wtk_offinfo_t));

    offInfo->num = len;

    // id off len
    offInfo->val = wtk_malloc(3*sizeof(OFF_TYPE)*len);

    return offInfo;
}



int wtk_offinfo_delete(wtk_offinfo_t *offInfo) {
    if(offInfo->val) {
        wtk_free(offInfo->val);
    }

    wtk_free(offInfo);

    return 0;
}



int wtk_offinfo_load(wtk_offinfo_t *info, wtk_source_t *s) {
    int i;
    int j;
    int step = sizeof(OFF_TYPE);

    // read all data
    wtk_source_fill(s, (char *)info->val, info->num*step*3);

    OFF_TYPE tmp;
    OFF_TYPE *sptr= info->val;

    unsigned char *cptr = (unsigned char*)info->val;
    for(i=0; i<info->num*3; ++i) {
        tmp = *cptr; ++cptr;

        for(j=1; j<step; ++j) {
            tmp += (*cptr)<<8;
            ++cptr;
        }

        *sptr = tmp;
        ++sptr;
    }

    return 0;
}



int wtk_offinfo_get(wtk_offinfo_t *info, int tid, OFF_TYPE *off, OFF_TYPE *len) {
    int s = 0;
    int e = info->num;
    int mid;

    OFF_TYPE *ptr = NULL;
    OFF_TYPE *val = info->val;
    OFF_TYPE id;

    while(s<e) {
        mid = (s+e)>>1;
        ptr = val+mid*3;
        id = *ptr;

        if(id==tid) {
            break;
        } else if(id<tid) {
            s = mid+1;
        } else {
            e = mid-1;
        }
    }

    // if not find, the result is s=e+1, and due to [(k)+(k+1)]>>1 will always return k,
    // left k+1 uncheck, so we have to check it final
    if(id!=tid) {
        ptr = val+s*3;
        id = *ptr;
    }

    if(id==tid) {
        *off = *(ptr+1);
        *len = *(ptr+2);
        return 0;
    } else {
        *off = -1;
        *len = -1;
        return -1;
    }
}


int wtk_offinfo_at(wtk_offinfo_t *info, int i, OFF_TYPE *id, OFF_TYPE *off, OFF_TYPE *len) {
    if(i>=info->num) {
        return -1;
    }

    OFF_TYPE *ptr = info->val + i*3;

    *id = *ptr;
    *off = *(ptr+1);
    *len = *(ptr+2);

    return 0;
}


int wtk_offinfo_print(wtk_offinfo_t *info) {
    int i;
    wtk_strbuf_t *buf = wtk_strbuf_new(1024, 1.0);

    for(i=0; i<info->num*3; ++i) {
        wtk_strbuf_push_f(buf, "%d ", info->val[i]);
        if(2==i%3) {
            printf("%.*s\n", buf->pos, buf->data);
            wtk_strbuf_reset(buf);
        }
    }

    wtk_strbuf_delete(buf);

    return 0;
}

